package com.gltqe.cipher;


import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.lang.reflect.Field;

/**
 * 自定义 Jackson序列化器
 *
 * @author gltqe
 * @date 2023/6/14 15:03
 **/
public class CipherDeserializer extends JsonDeserializer<Object> {

    private static ObjectMapper mapper = new ObjectMapper();

    private CipherHandle cipherHandle;

    private Class<?> beanClass;

    public CipherDeserializer(CipherHandle cipherHandle) {
        this.cipherHandle = cipherHandle;
    }


    /**
     * 反序列化
     *
     * @author gltqe
     * @date 2023/6/15 16:20
     **/
    @Override
    public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        // 获取字段的值
        JsonNode rootNode = jsonParser.readValueAsTree();
        Object obj = null;
        try {
            // 获取实例
            obj = beanClass.newInstance();
            // 获取请求参数所有字段名
            Field[] declaredFields = beanClass.getDeclaredFields();
            if (declaredFields.length > 0) {
                for (Field field : declaredFields) {
                    String fieldName = field.getName();
                    Cipher annotation = field.getAnnotation(Cipher.class);
                    field.setAccessible(true);
                    JsonNode node = rootNode.get(fieldName);
                    if (node != null) {
                        String fieldValue = node.asText();
                        if (annotation != null) {
                            // 解密
                            Object value = this.cipherHandle.decryptHandle(annotation, fieldValue);
                            Class<?> type = field.getType();
                            if (String.class.equals(type)) {
                                field.set(obj, value);
                            } else {
                                Object o = mapper.readValue(String.valueOf(value), type);
                                field.set(obj, o);
                            }
                        } else {
                            field.set(obj, fieldValue);
                        }
                    }
                }
            }
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return obj;
    }

    /**
     * 获取加解密处理器
     *
     * @return: org.gltqe.cipher.CipherHandle
     * @author gltqe
     * @date 2023/6/16 9:31
     **/
    public CipherHandle getCipherHandle() {
        return cipherHandle;
    }

    /**
     * 设置反序列化类
     *
     * @param beanClass
     * @author gltqe
     * @date 2023/6/16 14:53
     **/
    public void setBeanClass(Class<?> beanClass) {
        this.beanClass = beanClass;
    }
}
